package com.itheima.tanhua.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.itheima.tanhua.api.db.UserInfoServiceApi;
import com.itheima.tanhua.api.mongo.CommentApi;
import com.itheima.tanhua.api.mongo.MovementServiceApi;
import com.itheima.tanhua.exception.ConsumertException;
import com.itheima.tanhua.utils.Constants;
import com.itheima.tanhuan.CommentType;
import com.itheima.tanhuan.pojo.db.UserInfo;
import com.itheima.tanhuan.pojo.mongo.Comment;
import com.itheima.tanhuan.pojo.mongo.Movement;
import com.itheima.tanhuan.vo.mongo.CommentVo;
import com.itheima.tanhuan.vo.mongo.PageResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class CommentService {
    @DubboReference
    CommentApi commentApi;
    @DubboReference
    UserInfoServiceApi userInfoServiceApi;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @DubboReference
    MovementServiceApi movementServiceApi;

    //评论列表
    public PageResult comments(String movementId, Integer page, Integer pagesize) {
        List<CommentVo> commentVoList = new ArrayList<>();
        String uid = stringRedisTemplate.opsForValue().get("UID");
        //评论列表：通过动态id来查找每一条评论信息，和个人信息，返回前端。
        //1.通过动态id找到每一条评论
        List<Comment> comments = commentApi.findByMovementId(new ObjectId(movementId), CommentType.COMMENT);
        //2.将每一条评论加上评论人信息
        List<Long> userIds = CollUtil.getFieldValues(comments, "userId", Long.class);
        Map<Long, UserInfo> byIds = userInfoServiceApi.findByIds(userIds, null);
        for (Comment comment : comments) {
            //判断每一条评论是否我有过点赞.登录id+评论id
            Object o = stringRedisTemplate.opsForHash().get(Constants.MOVEMENT_LIKE_HASHKEY + uid, comment.getId());
            CommentVo init = CommentVo.init(byIds.get(comment.getUserId()), comment);
            //点过赞的评论，展示已点赞
            if (ObjectUtil.isNotEmpty(o)) {
                init.setHasLiked(Convert.toInt(o));
            }
            commentVoList.add(init);
        }
        return new PageResult(page, pagesize, comments.size(), commentVoList);
    }

    //提交消息
    public void commentsPost(String movementId, String comment) {
        Comment comment1 = new Comment();
        //提交评论，生成一个mongodb的评论，从redis获得评论者id，从动态获得被评论的id，点赞数是0
        String uid = stringRedisTemplate.opsForValue().get("UID");
        ObjectId objectId = new ObjectId(movementId);
        Movement movement = movementServiceApi.getmoveById(objectId);

        comment1.setPublishId(objectId);
        comment1.setCommentType(CommentType.COMMENT.getType());
        comment1.setContent(comment);
        comment1.setUserId(Convert.toLong(uid));
        comment1.setPublishUserId(movement.getUserId());
        comment1.setCreated(System.currentTimeMillis());
        comment1.setLikeCount(0);

        Boolean falg = commentApi.commentPost(comment1);

    }

    //评论点赞
    public Integer likeComment(String id) {
        //1.从缓存中取数据，有代表已经点赞了，返回一点赞
        //redis存储规格，大名，评论id，值点赞总数
        CommentType like = CommentType.LIKE;
        String name = like.name();
        System.out.println(name);


        String uid = stringRedisTemplate.opsForValue().get("UID");
        Object o = stringRedisTemplate.opsForHash().get("LikeComment_", uid);//用户是唯一的
        if (ObjectUtil.isNotEmpty(o)) {
            //已经点赞
            throw new ConsumertException("已经点赞");
        }
        //2.没点赞，根据评论id，，修改对应评论喜欢数+1，点赞过程存储在redis：为了快速查询，
        Integer count = commentApi.likeCommentCount(id);
        //设置格式：动态评论登录者+评论id+点赞数
        stringRedisTemplate.opsForHash().put(Constants.MOVEMENTS_RECOMMEND + uid, id, count + "");
        //生成一条独立的记录用户点赞的行为记录,pulishId用来存评论id
        Comment comment = commentApi.findById(id);
        Comment comment1 = new Comment();

        comment1.setPublishId(comment.getId());
        comment1.setCommentType(CommentType.LIKE.getType());
        comment1.setContent(null);
        comment1.setUserId(Convert.toLong(uid));
        comment1.setPublishUserId(comment.getPublishUserId());
        comment1.setCreated(System.currentTimeMillis());

        comment1.setLikeCount(1);
        return count;
    }

    public Integer dislikeComment(String id) {
        //1.从缓存中取数据，没有代表已经点赞了，取消点赞
        //redis存储规格，大名，评论id，值点赞总数
        String uid = stringRedisTemplate.opsForValue().get("UID");
        Object o = stringRedisTemplate.opsForHash().get(Constants.MOVEMENTS_RECOMMEND + uid, id);//用户是唯一的
        if (ObjectUtil.isEmpty(o)) {
            //没有点赞
            throw new ConsumertException("没有点赞");
        }
        //2.点赞，根据评论id，，修改对应评论喜欢数-1，点赞过程存储在redis：为了快速查询，方便不重复取消点赞
        Integer count = commentApi.dislikeCommentCount(id);
        stringRedisTemplate.opsForHash().delete(Constants.MOVEMENTS_RECOMMEND + uid, id);
        //TODO 3.优化评论列表，点赞显红
        //3.删除点赞记录,根据评论id和登录者，类型来删除
        commentApi.deletLike(uid, id, CommentType.LIKE.getType());
        return count;
    }

    //动态喜欢
    public Integer likeMove(String movementId) {
        //1.从redis中取数据，有则已经点赞，抛异常
        Object o = stringRedisTemplate.opsForHash().get(Constants.MOVEMENT_LIKE_HASHKEY, movementId);
        if (ObjectUtil.isNotEmpty(o)) {
            throw new ConsumertException("已经点赞");
        }

        Comment comment1 = new Comment(); //2.新增数据
        //获得登录者id
        String uid = stringRedisTemplate.opsForValue().get("UID");
        //判断是不是已经点过赞了。
        Boolean falg = commentApi.isLike(movementId, CommentType.LIKE.getType(), Convert.toLong(uid));
        if (falg) {
            throw new ConsumertException("已经点赞");
        }
        ObjectId objectId = new ObjectId(movementId);
        //动态点赞加一
        Integer count = movementServiceApi.likeComment(objectId);
        Movement movement = movementServiceApi.getmoveById(objectId);//查找动态

        comment1.setPublishId(objectId);
        //喜欢类型
        comment1.setCommentType(CommentType.LIKE.getType());
        //内容是null
        comment1.setContent(null);
        //登录者
        comment1.setUserId(Convert.toLong(uid));
        //动态推送者
        comment1.setPublishUserId(movement.getUserId());
        //当前时间
        comment1.setCreated(System.currentTimeMillis());
        //喜欢数
        comment1.setLikeCount(count);
        //保存数据
        //3.设置redis
        stringRedisTemplate.opsForHash().put(Constants.MOVEMENT_LIKE_HASHKEY, movementId, "1");
        return count;

    }

    public Integer dislikeMove(String movementId) {
        //获得登录者id
        String uid = stringRedisTemplate.opsForValue().get("UID");
        //.根据动态，点赞生成互动数据
        //1.从redis中取数据，没有数据代表没有点赞，抛异常
        Object o = stringRedisTemplate.opsForHash().get(Constants.MOVEMENT_LIKE_HASHKEY, movementId);
        if (ObjectUtil.isEmpty(o)) {
            throw new ConsumertException("您还没有点赞");
        }
        //防止redis崩坏，从数据库中查找数据
        Boolean isLikeMove = commentApi.isLike(movementId, CommentType.LIKE.getType(), Convert.toLong(uid));
        if (!isLikeMove) {
            throw new ConsumertException("您还没有点赞");
        }
        //删除喜欢动态互动数据
        Boolean deletLike = commentApi.deletLike(uid, movementId, CommentType.LIKE.getType());
        if (!deletLike) {
            throw new ConsumertException("取消失败");
        }
        Integer count = movementServiceApi.decreaseLikeMove(movementId);//将动态喜欢数-1,返回喜欢数
        //删除内存中的喜欢动态标识
        stringRedisTemplate.opsForHash().delete(Constants.MOVEMENT_LIKE_HASHKEY, movementId);

        return count;
    }
}

